/*******************************************************************************
 *	                           bsp nor spi.c
 *******************************************************************************/
#include "bsp.h"
#include "pincfg.h"
#include "nor_cmd.h"
#include "mytype.h"
#include "bsp_spi.h"

/*****************************************************************************
 * @brief   IO 描述
 *****************************************************************************/
#define SPIn SPI2
#define ISR_IRQn SPI2_IRQn

/*****************************************************************************
 * @brief   hal init.
 * @param   none
 * @return  none
 *****************************************************************************/
void nor_spi_init(void)
{
	SPI_InitTypeDef cfg;

	intx_alloc();

	intx_disable();

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);
	RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, ENABLE);
	RCC_APB1PeriphResetCmd(RCC_APB1Periph_SPI2, DISABLE);

	intx_enable();

	// SPI 配置
	cfg.SPI_Mode = SPI_Mode_Master;
	cfg.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
	cfg.SPI_CPHA = SPI_CPHA_2Edge;
	cfg.SPI_CPOL = SPI_CPOL_High;
	cfg.SPI_DataSize = SPI_DataSize_8b;
	cfg.SPI_FirstBit = SPI_FirstBit_MSB;
	cfg.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
	cfg.SPI_CRCPolynomial = 0;
	cfg.SPI_NSS = SPI_NSS_Soft;

	SPI_Init(SPIn, &cfg);

	SPI_Cmd(SPIn, ENABLE);

	// send 0xff
	nor_spi_wb(0xFF);
}

/*****************************************************************************
 * @brief   cs ctr.
 * @param   none
 * @return  none
 * @ Pass/ Fail criteria: none
 *****************************************************************************/
void nor_spi_cs(uint8_t st)
{
	if (st)
		spi_cs.en();
	else
		spi_cs.dis();
}

/*****************************************************************************
 * @brief   spi mode select.
 *****************************************************************************/
void nor_hal_mode_spi(void)
{
}

void nor_hal_mode_qpi_out(void)
{
}

void nor_hal_mode_qpi_in(void)
{
}

/*****************************************************************************
 * @brief   spi micro.
 *****************************************************************************/
#define spi_read_delay() NOP8()
#define spi_rx_reset() rd = SPIn->DATAR
#define spi_send(dat) SPIn->DATAR = dat
#define is_spi_rx_ready() (SPIn->STATR & SPI_STATR_RXNE)
#define is_spi_tx_full() ((SPIn->STATR & SPI_STATR_TXE) == 0)
#define is_spi_tx_empty() (SPIn->STATR & SPI_STATR_TXE)
#define is_spi_busy() (SPIn->STATR & SPI_STATR_BSY)
#define spi_read() SPIn->DATAR
/*****************************************************************************
 * @brief   spi data read.
 *****************************************************************************/
uint8_t nor_spi_rb(void)
{
	// send data
	spi_send(0xFF);
	spi_read_delay();

	// wait for trans complete
	while (!is_spi_rx_ready())
		;

	// read data
	return (spi_read());
}

void nor_spi_wb(uint8_t dataW)
{
	volatile uint8_t rb;

	// send data
	spi_send(dataW);
	spi_read_delay();

	// wait for trans complete
	while (!is_spi_rx_ready())
		;

	rb = spi_read();

	(void) rb;
}

/*****************************************************************************
 * @brief   spi data write.
 *****************************************************************************/
uint8_t nor_spi_write(const uint8_t *dataw, uint32_t Len)
{
	volatile uint8_t rb;

	while (Len--)
	{
		// send data
		spi_send(*dataw++);

		spi_read_delay();

		while (is_spi_tx_full())
			;
		// while (!is_spi_rx_ready())
		//	;
		//	rb = spi_read();
	}

	while (is_spi_busy())
		;

	// read data
	rb = spi_read();

	(void)rb;

	return (0);
}

/*****************************************************************************
 * @brief   spi data read.
 *****************************************************************************/
uint8_t nor_spi_read(uint8_t *datar, uint32_t Len)
{
	uint32_t rcnt = 0;

	while (Len--)
	{
		// send data
		spi_send(0xFF);

		spi_read_delay();

		while (!is_spi_rx_ready())
			;

		datar[rcnt++] = spi_read();
	}

	return 0;
}

void nor_spi_dma_read(uint8_t *datar, uint32_t Len)
{
}

/*****************************************************************************
 * @brief   qpi data write.
 *****************************************************************************/
uint8_t nor_qpi_write(const uint8_t *dataw, uint32_t Len)
{
	return 0;
}

/*****************************************************************************
 * @brief   qpi data read.
 *****************************************************************************/
uint8_t nor_qpi_read(uint8_t *datar, uint32_t Len)
{
	return 0;
}
